<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
</head>

<body>

</body>

</html>
<script>
    // var obj = Object.create(null)
    // console.log(obj)
    // console.log(Object.getPrototypeOf(obj))
    // var a = new Object(null)
    // console.log("toString" in obj)
    // console.log("toString" in a)

    //     ! function () {
    //         function MyClass() {}
    //         var Proto = {
    //             x: 2,
    //             y: 3
    //         }
    //         MyClass.prototype = Proto
    //         var obj = new MyClass()
    //         console.log(obj)
    //         console.log(obj.x, obj.y)
    //         var Proto = {
    //             x: 2,
    //             y: 3
    //         }
    //         var obj = Object.create(Proto)
    //         console.log(obj)
    //         console.log(obj.x, obj.y)
    //     }()

    //     // 属性对象
    //     ! function () {
    //         var obj = {
    //             x: 2,
    //             y: 3
    //         };
    //         var obj = Object.create(Object.prototype, {
    //             x: {
    //                 value: 2
    //             },
    //             y: {
    //                 value: 3
    //             }
    //         })
    //         console.log(obj)
    //         obj.x = 6
    //         console.log(obj.x)
    //         var obj = Object.create(Object.prototype, {
    //             x: {
    //                 value: 2
    //             }
    //         })
    //         console.log(obj.x)
    //         console.log(Object.getOwnPropertyDescriptor(obj, "x"))
    //         Object.defineProperty(obj, "y", {
    //             value: 3,
    //             enumerable: true
    //         })
    //         console.log(Object.getOwnPropertyDescriptor(obj, "y"))
    //         Object.defineProperty(obj, "z", {
    //             value: function () {
    //                 return 1
    //             },
    //             enumerable: true
    //         })
    //         console.log(Object.getOwnPropertyDescriptor(obj, "z"))
    //         console.log(Object.keys(obj))
    //     }()

    //     // 访问器的属性
    //     ! function () {
    //         var obj = Object.create(Object.prototype, {
    //             x: {
    //                 get: function (a) {console.log("get called")},
    //                 set:function(a){console.log("set called")}
    //             }
    //         })
    //         console.log(obj.x)
    //         obj.x = 1
    //     }()

    //     !function(){
    //         var obj = {get x(){console.log("get called") },set x(v){console.log("set called")}}
    //         console.log(obj.x)
    //     }()

    //     !function(){
    //         // 闭包和访问器结合
    //         function createObject(){
    //             var _x
    //             return {get x(){return _x;},set x(v) {_x = v}}
    //         }
    //         var obj = createObject()
    //         console.log(obj.x)
    //         console.log(obj.x = 5)
    //     }()

    // Object.create实现
    ! function () {
        var o = function () { return { get x() { return _x }, set x(v) { return _x = v } } }
        // console.log(o)
        var obj = Object.create(o, undefined)
        // console.log(obj.x = 5)
        console.log(obj.x)
        // obj.y = 6
        console.log(obj.y)
    }()


    !function () {
        function Shape() {
            this.x = 0,
            this.y = 0
        }
        Shape.prototype.move = function (x, y) {
            this.x += x;
            this.y += y;
            console.info("Shape moved", this.x, this.y)
        }
        function Rectangle() {
            Shape.call(this)
        }
        console.log(Rectangle())
        Rectangle.prototype = Object.create(Shape.prototype)
        console.log(Rectangle())
        // Rectangle.prototype.constructor = Rectangle
        var rect = new Rectangle()
        console.log("Is rect an instanceof of Rectangle", rect instanceof Rectangle)
        console.log("Is rect an instanceof of Shape", rect instanceof Shape)
        console.log(rect.move(1, 1))

        // 继承多个对象
        function SupperClass(x) {
            // this.x += 20
            console.log("x")
        }
        function OtherSuperClass(y) {
            // this.y +=1
            console.log("y")
        }
        OtherSuperClass.prototype.other = function () { console.log('other func') }
        SupperClass.prototype.other1 = function () { console.log('super func') }
        function MyClass(x) {
            SupperClass.call(this)
            OtherSuperClass.call(this)
        }
        // MyClass.prototype = Object.create(SupperClass.prototype)
        Object.assign(MyClass.prototype, OtherSuperClass.prototype, SupperClass.prototype);
        MyClass.prototype.constructor = MyClass;
        console.info(MyClass.prototype)
        var caa = new MyClass()
        console.log(caa)
        caa.other()
        caa.other1()
        //Object.assing()  //将后面的原型对象深度复制到第一个对象里面
        console.log(caa instanceof MyClass, caa instanceof SupperClass, caa instanceof OtherSuperClass)
        console.log(caa.constructor)
    }()

    // Object.create() 的 "propertyObject"
    !function(){
        var o
        o = Object.create(null)
        console.log(o)
        o = {}
        console.log(o)
        o = Object.create(Object.prototype,{
            foo:{
                writable:true,
                configurable:true,
                value:"hello"
            },
            bar:{
                configurable:true,
                // writable:true,
                get:function(){
                    return 10
                },
                set:function(value){
                    console.log("setting `o.bar` to",value)
                    return value
                }
            }
        })
        console.log(o.bar)
        o.bar = 11
        console.log(o.bar)
    }()


    !function(){
        function Constructor(){}
        o = new Constructor()
        o = Object.create(Constructor.prototype)
        o = Object.create({},{p:{value:42}})
        console.log(o.p)
        o.p = 24
        console.log(o.p)
        o.q = 12
        for (var a in o){
            console.log(a)
        }
        o2 = Object.create({},{p:{value:22,enumerable:true,writable:true,configurable:true}})
        for(var a in o2){
            console.log(a)
        }
    }()

</script>